package com.clps.myssm.filters;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.clps.digital.common.ErrorCode;
import com.clps.digital.common.ResultUtils;
import com.clps.digital.util.NoAuthPath;
import com.clps.digital.util.TokenCache;
import com.clps.digital.util.UserContext;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author: Chase
 * @date: 2024/9/2 11:12
 * @Version: 1.0
 * @description:
 */

@WebFilter("*.do")
public class UserAuthFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        String operate = servletRequest.getParameter("operate");
        if(StrUtil.isEmpty(operate)){
            throw new RuntimeException("operate不能为空！");
        }
        // 校验是否要登录才能访问的路径
        if (isNoAuthorized(operate)) {
            // 不用登录的直接放行
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            Long userId = getUserId((HttpServletRequest) servletRequest);
            // 不存在userId，返回错误信息
            if (ObjUtil.isEmpty(userId)) {
                String jsonStr = JSONUtil.toJsonStr(ResultUtils.error(ErrorCode.TOKEN_ERROR));
                PrintWriter out = servletResponse.getWriter();
                out.print(jsonStr);
                out.flush();
                return;
            }

            // 存在userId，将userId放入上下文中，并且放行
            UserContext.setUser(userId);
            filterChain.doFilter(servletRequest, servletResponse);
            UserContext.removeUser();
        }
    }

    @Override
    public void destroy() {

    }

    /**
     * 判断访问路径是否需要登录
     * @param operate
     * @return
     */
    private Boolean isNoAuthorized(String operate) {
        for (String path : NoAuthPath.getNoAuthPathList()) {
            if (path.equals(operate)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取userId
     * @param request
     * @return
     */
    private Long getUserId(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StrUtil.isEmpty(token)) {
            return null;
        } else {
            // 校验token合法性(后端是否存在或者是否过期)
            Long userId = TokenCache.get(token);
            if (ObjUtil.isEmpty(userId)) {
                return null;
            }
            return userId;
        }
    }
}
